package vn.cent.games.findnumber.main;

import java.util.Map.Entry;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;

import vn.cent.games.findnumber.beans.GameBean;
import vn.cent.games.findnumber.beans.PlayerBean;
import vn.cent.games.findnumber.utils.Commands;
import vn.cent.games.findnumber.utils.Constants;

import com.smartfoxserver.v2.api.CreateRoomSettings;
import com.smartfoxserver.v2.entities.Room;
import com.smartfoxserver.v2.entities.SFSRoomRemoveMode;
import com.smartfoxserver.v2.entities.User;
import com.smartfoxserver.v2.entities.data.ISFSObject;
import com.smartfoxserver.v2.entities.data.SFSObject;
import com.smartfoxserver.v2.exceptions.SFSCreateRoomException;
import com.smartfoxserver.v2.exceptions.SFSJoinRoomException;
import com.smartfoxserver.v2.extensions.BaseClientRequestHandler;

/**
 * manage ready message from user
 * 
 * @author TV.Vinh
 * @version 1.0
 *
 */

public class ReadyHandler extends BaseClientRequestHandler{

	/**
	 * find available room for user, if not create one 
	 */
	@Override
	public void handleClientRequest(User sender, ISFSObject params) {
		
		FindNumberExtension gameExt = (FindNumberExtension) getParentExtension();
		// get current game rooms
		ConcurrentHashMap<Integer, GameBean> list_games = gameExt.getGames();
		
		GameBean game = GetAvaiableRoom(list_games);
		ISFSObject resObj = new SFSObject();
		trace("FN v1 FIND & JOIN ROOM");
		// has room to join
		if(game != null){
			
			try {
				this.getApi().joinRoom(sender, game.getRoom(), "", false, sender.getLastJoinedRoom());
				game.getPlayers().put(sender.getId(), 
						new PlayerBean(sender.getId(), game.getRoom().getId(), true, sender));
				game.setGuest(sender.getId());
				resObj.putBool("isH", false);
				gameExt.send(Commands.CMD_getREADY, resObj, sender);
				
				// TODO let's start the game
				game.startGame(game.getRoom().getPlayersList(), gameExt);
				trace("FN v1 JOIN OK");
			} catch (SFSJoinRoomException e) {
				e.printStackTrace();
			}
			
		} else { // no?, create one and set room up
			
			// create room
			try {
				int rand = new Random().nextInt(100); 
				// set up room settings
				CreateRoomSettings settings = new CreateRoomSettings();
				settings.setName("Room" + sender.getId() + rand);
				settings.setMaxUsers(Constants.MAX_USER);
				settings.setGame(true);
				settings.setDynamic(true);
				settings.setAutoRemoveMode(SFSRoomRemoveMode.WHEN_EMPTY);
				
				// make new room
				Room room = this.getApi().createRoom(gameExt.getParentZone(), settings, sender);
				// join player to room
				this.getApi().joinRoom(sender, room);

				// create game
				game = new GameBean(room, sender.getId());
				game.getPlayers().put(sender.getId(), 
						new PlayerBean(sender.getId(), room.getId(), true, sender));
				
				// add "pending" game
				list_games.put(room.getId(), game);
				
				// TODO tell player to wait
				resObj.putBool("isH", true);
				gameExt.send(Commands.CMD_getREADY, resObj, sender);
				
				trace("FN v1 CREATE OK");
//				trace("Player: " + sender.getName() + " has created room: " + room.getName());
			} catch (SFSCreateRoomException e) {
				e.printStackTrace();
			} catch (SFSJoinRoomException e) {
				e.printStackTrace();
			}
			
		}
	}
	
	/**
	 * 
	 * @param game : list of current active games
	 * @return: id of free room
	 */
	private GameBean GetAvaiableRoom(ConcurrentHashMap<Integer, GameBean> games){
		
		// iterate over entire active games, find if any room is free
		for (Entry<Integer, GameBean> iterable_element : games.entrySet()) {
			GameBean game = iterable_element.getValue();
			if(!game.isStarted()){
				return game;
			}
		}
		
		return null;
	}
}
